#1.函数参数
    # 形参: *args **kwargs
    # 实参: 位置传参 关键字传参
    # 实参中的所有额外的位置参数会被*args收集,收集成一个元组
    # 实参中所有的额外的关键字参数会被**kwargs收集,收集成一个字典

# def test(a,*args,**kwargs):
#     print(args,*args)
#     print(kwargs)
#     print({"damu":"123",**kwargs})
#
# test(1,2,3,4,5,6,7,8,c=8,d=2,e=3,f=4,g=5,h=6,i=7)


#2.装饰器
# def wrap(fn):
#     def inner(*args, **kwargs):
#         print('+++++++')
#         res = fn(*args, **kwargs)
#         print("-------")
#         return res
#     return inner
#
#
# @wrap #test = wrap(test)
# def test(a):
#     print('test')
#     return a
#
# print(test(1))
#
# @wrap #test2 = wrap(test2)
# def test2(a,b):
#     print('test2')
#     return a + b
#
# print(test2(1,2))

# 3.装饰器传参
# def wrap(msg):
#     def log(fn):
#         def inner(*args, **kwargs):
#             print(msg + fn.__name__ + "函数启动了")
#             res = fn(*args, **kwargs)
#             return res
#         return inner
#     return log
# @wrap("❤") # test = wrap("❤")(test)
# def test():
#     print("test")
#
# test()


# 闭包
# 1. 函数要产生嵌套
# 2. 内部函数要使用外部函数的变量
# 3. 内部函数要被返回

# 类
class Student:
    i = 0
    def __init__(self,name,age):
        self.name=name
        self.age=age

# 实例化(对类进行调用 其实最终调用的是构造函数)
# 实例化的结果是返回一个实例
# s = Student()
# s2 = Student()

# 实例(实例是一个和字典很像的结构)
# s可以被称为是Student的实例
# print(s,s.__dict__)
# print(s2,s2.__dict__)

# 对象 = 实例
# s也可以被称为是Student创建出来的对象

# 构造函数 self
# 在类中默认都有一个__init__函数,这个函数被称为构造函数
# 在类被实例化时 其实最终调用的是构造函数 返回的就是self
# self默认长这样:{}, self是一个类似于字典的结构

# 实例属性 = 实例变量
# 在构造函数中除了self以外的其他参数 我们称为实例属性(实例变量)
# name,age可以称为实例属性
s3 = Student("damu",18)
print(s3,s3.__dict__)

# 类属性 = 类变量
# 类变量定义在类中且在函数体之外
# i 就是类变量
# 类变量对于所有的实例都是共用的
print(s3.i)













